package com.lenovo.smarttraffic.ui.activity;

import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.widget.TextView;

import com.lenovo.smarttraffic.Constant;
import com.lenovo.smarttraffic.R;
import com.lenovo.smarttraffic.bean.GsonBean.MetroInfoBean;
import com.lenovo.smarttraffic.bean.MetroCalBean;
import com.lenovo.smarttraffic.bean.MetroResultBean;
import com.lenovo.smarttraffic.ui.adapter.MetroResultRecyclerAdapter;

import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;

/**
 * Created by Caleb.F
 * on 2019-12-08
 * at 15:42
 */
public class MetroResultActivity extends BaseActivity {

    private TextView mTvMoney1;
    private TextView mTvDistance1;
    private TextView mTvMoney2;
    private TextView mTvDistance2;
    private TextView mTvMoney3;
    private TextView mTvDistance3;
    private TextView[] mTextViewMoney;
    private TextView[] mTextViewDistance;


    private RecyclerView mMetroRecyclerResult1;
    private RecyclerView mMetroRecyclerResult2;
    private RecyclerView mMetroRecyclerResult3;
    private RecyclerView[] mRecyclerViews;
    private HashMap<String, List<String>> allSitesMap;//所有的站点的集合
    private HashMap<String, List<String>> transforLineMap;//站点对应的换乘线
    private HashMap<String, List<String>> transforSitesMap;//线对用的换乘点
    private List<MetroCalBean> mMetroCalBeans;
    private MetroInfoBean metroInfoBean;
    private static final String TAG = "MetroResultActivity";


    @Override
    protected void onCreate(@Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EventBus.getDefault().register(this);
        initView();
    }

    @Subscribe(threadMode = ThreadMode.BACKGROUND, sticky = true)
    public void getMetroInfo(MetroResultBean metroResultBean) {
        allSitesMap = metroResultBean.getAllSpotMap();
        transforLineMap = metroResultBean.getTransforLineMap();
        transforSitesMap = metroResultBean.getTransforSpotMap();
        Message message = new Message();
        message.what = 1;
        handler.sendMessage(message);
    }

    Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {
            switch (msg.what) {
                case 1:
                    List<List<String>> mlists = CalculateRoute(getIntent().getStringExtra(Constant.METRO_START_SPOT), getIntent().getStringExtra(Constant.METRO_END_SPOT));
                    initRecyclerData(mlists);
                    showRecyclerView();
                    break;
            }
            return false;
        }
    });

    /**
     * 三个recyclerView
     */
    private void showRecyclerView() {
        MetroResultRecyclerAdapter metroResultRecyclerAdapter;
        for (int i = 0; i <3 ; i++) {
            mRecyclerViews[i].setLayoutManager(new LinearLayoutManager(this,LinearLayoutManager.VERTICAL,false));
        }
        if(mMetroCalBeans.size()>=3){
            for (int i = 0; i <3; i++) {
                metroResultRecyclerAdapter = new MetroResultRecyclerAdapter(mMetroCalBeans.subList(0, 3), MetroResultActivity.this,i);
                mRecyclerViews[i].setAdapter(metroResultRecyclerAdapter);
                mTextViewMoney[i].setText(mMetroCalBeans.get(i).getAllPriceAccount()+"元");
                mTextViewDistance[i].setText(mMetroCalBeans.get(i).getAllSiteAccount()+"站");
            }
        }
        else if(mMetroCalBeans.size()==1){
            metroResultRecyclerAdapter = new MetroResultRecyclerAdapter(mMetroCalBeans, MetroResultActivity.this,0);
           mRecyclerViews[0].setAdapter(metroResultRecyclerAdapter);
           mTvMoney1.setText( mMetroCalBeans.get(0).getAllPriceAccount()+"元");
           mTvDistance1.setText(mMetroCalBeans.get(0).getAllSiteAccount()+"站");
        }
        else if(mMetroCalBeans.size()==2){
            for (int i = 0; i <2 ; i++) {
                metroResultRecyclerAdapter = new MetroResultRecyclerAdapter(mMetroCalBeans, MetroResultActivity.this,i);
                mRecyclerViews[i].setAdapter(metroResultRecyclerAdapter);
                mTextViewMoney[i].setText(mMetroCalBeans.get(i).getAllPriceAccount()+"元");
                mTextViewDistance[i].setText(mMetroCalBeans.get(i).getAllSiteAccount()+"站");
            }
        }
    }

    private void initRecyclerData(List<List<String>> lists) {
        mMetroCalBeans = new ArrayList<>();
        for (List<String> item :
                lists) {
            ArrayList<String> strings = new ArrayList<>();//换乘点
            ArrayList<String> strings1 = new ArrayList<>();//线路
            HashSet<String> commonSites = new LinkedHashSet<>();//普通站点
            ArrayList<MetroCalBean.TransForSite> transForSites = new ArrayList<>();
            for (String item1 :
                    item) {
                if (item1.contains("S:")) {
                    strings.add(item1.substring(2));
                } else {
                    strings1.add(item1.substring(2));
                }
            }

            for (int i = 0; i < strings1.size(); i++) {
                List<String> list = allSitesMap.get(strings1.get(i));
                //换乘点之间的路线怎么走
                int i1 = list.indexOf(strings.get(i));
                int i2 = list.indexOf(strings.get(i + 1));
                if (i1 < i2) {
                    for (int i3 = i1; i3 <= i2; i3++) {
                        commonSites.add(list.get(i3));
                    }
                } else {
                    for (int i3 = i1; i3 >= i2; i3--) {
                        commonSites.add(list.get(i3));
                    }
                }
            }
            ArrayList<String> commomSiteList = new ArrayList<>();
            commomSiteList.addAll(commonSites);
            //去找到换乘点在列表中的位置
            for (int i = 1; i <strings.size()-1 ; i++) {
                String s = String.valueOf(commomSiteList.indexOf(strings.get(i)));
                transForSites.add(new MetroCalBean.TransForSite(strings.get(i),s,strings1.get(i)));
            }
            mMetroCalBeans.add(new MetroCalBean(commomSiteList, transForSites,
                    String.valueOf(commonSites.size()), String.format(Locale.getDefault(),"%.2f",(commonSites.size() - 1) * 0.4)));
        }
        Collections.sort(mMetroCalBeans, new Comparator<MetroCalBean>() {
            @Override
            public int compare(MetroCalBean o1, MetroCalBean o2) {
                return Integer.parseInt(o1.getAllSiteAccount()) - Integer.parseInt(o2.getAllSiteAccount());
            }
        });
    }

//含有该地点的线路
    private List<String> getSpotLine(String Spot) {
        ArrayList<String> strings = new ArrayList<>();
        Set<Map.Entry<String, List<String>>> entries = allSitesMap.entrySet();
        for (Map.Entry<String, List<String>> item :
                entries) {
            for (String item1 :
                    item.getValue()) {
                if (item1.equals(Spot)) {
                    strings.add(item.getKey());
                }
            }
        }
        return strings;
    }

    //两条线之间的换乘点
    private List<String> getChangeSpot(String startLine, String endLine) {
        List<String> resultList = new ArrayList<>();
        for (String transforSite :
                transforSitesMap.get(startLine)) {
            for (String changeLine :
                    transforLineMap.get(transforSite)) {
                if (changeLine.equals(endLine)) {
                    resultList.add(transforSite);
                }
            }
        }
        return resultList;
    }

    //计算两点之间的路径
    private List<List<String>> CalculateRoute(String startSpot, String endSpot) {
        //遍历所有路径，找到站点所含有的所有线路
        List<String> spotLine = getSpotLine(startSpot);
        HashSet<String> allPaths = new HashSet<>();//先算地铁线路
        for (String item :
                spotLine) {
            loopRoad(item, endSpot, allPaths, "");
        }
        Log.d(TAG, "CalculateRoute: "+allPaths.toString());
        List<List<String>> lists = buildRoad(allPaths, startSpot, endSpot);
        return lists;

    }

    //递归遍历所有路径,不回头可以到则成功
    private void loopRoad(String startLine, String endSpot, Set<String> allPaths, String goPath) {
        //走了回头路，递归结束
        if (goPath.contains(startLine)) {
            return;
        }
        //走过的路径
        String nowPath = goPath + "@" + startLine;
        //找到终点，如果在同一条线上，第一个结果出来
        if (allSitesMap.get(startLine).contains(endSpot)) {
            allPaths.add(nowPath);
        }
        //所有的换乘站点,对应的换乘线
        for (String changeSiteItem : transforSitesMap.get(startLine)) {
            for (String changeLineItem :
                    transforLineMap.get(changeSiteItem)) {
                loopRoad(changeLineItem, endSpot, allPaths, nowPath);
            }
        }
    }


    /**
     * @param allPaths
     * @param startSpot
     * @param endSpot
     * @return 根据路线的走法确定换乘站点
     */
    private List<List<String>> buildRoad(HashSet<String> allPaths, String startSpot, String endSpot) {
        List<List<String>> lists = new ArrayList<>();
        for (String pathInfo :
                allPaths) {
            //每一个pathInfo的换乘线路
            List<String> path = Arrays.asList(pathInfo.substring(1).split("@"));

            ArrayList<String> road = new ArrayList<>();

            road.add("S:" + startSpot);
            boolean reach = true;
            for (int i = 0; i < path.size() - 1; i++) {
                //两条线之间的换乘点
                List<String> changeSpot = getChangeSpot(path.get(i), path.get(i + 1));
                //终点站不可作为换乘站点
                changeSpot.remove(endSpot);
                //换乘站点的问题，默认选择第一个，而且不允许走回头路
                if (changeSpot.size() != 0 && !road.contains("S:" + changeSpot.get(0))) {
                    road.add("L:" + path.get(i));
                    road.add("S:" + changeSpot.get(0));
                }
                else {
                    reach = false;
                    break;
                }
            }
            if (reach) {
                road.add("L:" + path.get(path.size() - 1));
                road.add("S:" + endSpot);
                lists.add(road);
            }
        }
        return lists;
    }


    private void initView() {
        initToolBar("出行建议");
        mTvMoney1 = findViewById(R.id.tv_money1);
        mTvDistance1 = findViewById(R.id.tv_distance1);
        mTvMoney2 = findViewById(R.id.tv_money2);
        mTvDistance2 = findViewById(R.id.tv_distance2);
        mTvMoney3 = findViewById(R.id.tv_money3);
        mTvDistance3 = findViewById(R.id.tv_distance3);
        mMetroRecyclerResult1 = findViewById(R.id.metro_recycler_result1);
        mMetroRecyclerResult2 = findViewById(R.id.metro_recycler_result2);
        mMetroRecyclerResult3 = findViewById(R.id.metro_recycler_result3);
      mRecyclerViews =new RecyclerView[]{
                mMetroRecyclerResult1,mMetroRecyclerResult2,mMetroRecyclerResult3
        };
      mTextViewMoney=new TextView[]{
              mTvMoney1,mTvMoney2,mTvMoney3
      };
      mTextViewDistance=new TextView[]{
              mTvDistance1,mTvDistance2,mTvDistance3
      };
    }

    @Override
    protected int getLayout() {
        return R.layout.activity_metro_reuslt;
    }


    @Override
    protected void onDestroy() {
        super.onDestroy();
        EventBus.getDefault().unregister(this);
    }
}
